home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 425_01 / tar / tape.c < prev    next >
Text File  |  1994-04-02  |  16KB  |  647 lines

  1. /* tape.c - handle (tape) archive for the Tar program (see file tar.c)
  2.  * Author: T.V.Shaporev
  3.  * Creation date: 14 Dec 1990
  4.  * Contains both MS-DOS and UNIX specific codes
  5.  * Called by many functions - see files tar.c store.c extract.c
  6.  */
  7. #include <stdio.h>
  8. #include <errno.h>
  9.  
  10. #include "sysup.h"
  11. #include "modern.h"
  12. #include "zippipe.h"
  13. #include "lzwhead.h"
  14. #include "compress.h"
  15. #include "define.h"
  16.  
  17. #ifdef MODERN
  18. #    include <string.h>
  19. #    include <stdlib.h>
  20. #else
  21. #    ifdef M_XENIX
  22. #        include <string.h>
  23. #    else
  24.         int strlen();
  25.         char *strcpy(), *strncpy(), *mktemp();
  26. #    endif
  27.     extern char *sys_errlist[];
  28.     extern int sys_nerr;
  29. #endif
  30. #ifdef MSDOS
  31. #    include <io.h>
  32. #    ifdef __TURBOC__
  33. #        include <dir.h>
  34. #    else
  35. #        include <direct.h>
  36. #    endif
  37. #else
  38.     int  creat(), open(), read(), write(), close();
  39.     long lseek();
  40. #endif
  41.  
  42. static int n_read, mblock, nblock, rblock, wblock;
  43. static int indread, indwrite;
  44. static char rerror[] = "Tar: tape read error\n";
  45.  
  46. static int  sread  __ARGS__((char*, int));
  47. static int  swrite __ARGS__((char*, int));
  48. static int  sback  __ARGS__((int));
  49. #ifdef MSDOS
  50. extern int  dread  __ARGS__((char*, int));
  51. extern int  dwrite __ARGS__((char*, int));
  52. extern int  dback  __ARGS__((int));
  53.  
  54. extern int  qparse __ARGS__((char*));
  55. extern int  qbegin __ARGS__((void));
  56. extern int  qread  __ARGS__((char*, int));
  57. extern int  qwrite __ARGS__((char*, int));
  58. extern int  qback  __ARGS__((int));
  59. #endif
  60. static void talign __ARGS__((long));
  61.  
  62. void printbs __ARGS__((int));
  63.  
  64. static void psyserr __ARGS__((void))
  65. {
  66.    if (errno < sys_nerr) (void)fprintf(myout, "%s\n", sys_errlist[errno]);
  67.    else                  (void)fprintf(myout, "error %d\n", errno);
  68. }
  69.  
  70. static int sread(buf, n) /* regular file reading */
  71. char *buf; register n;
  72. {
  73.    if ((n = read(handle, buf, n)) == -1) {
  74.       (void)fprintf(myout, "Tar: archive read error: "); psyserr();
  75.    }
  76.    return n;
  77. }
  78.  
  79. static int swrite(buf, n) /* regular file writing */
  80. char *buf; register n;
  81. {
  82.    if (write(hwrite, buf, n) != n) {
  83.       (void)fprintf(myout, "Tar: archive write error: ");
  84. #ifdef MSDOS
  85.       if (n != -1) (void)fprintf(myout,"disk full\n"); else
  86. #endif
  87.       psyserr();
  88.       n = -1;
  89.    }
  90.    return n;
  91. }
  92.  
  93. static int sback(n)
  94. register n;
  95. {
  96.    return lseek(handle, (long)-BLKSIZE*n, 1) < 0 ? -1 : n;
  97. }
  98.  
  99. #ifdef USE_COMPRESS
  100. static int zwrite __ARGS__((char*, int));
  101.  
  102. static int zwrite(buf, n) /* compressed file writing */
  103. char *buf; register n;
  104. {
  105.    cpiece(buf, n); return n;
  106. }
  107. #endif
  108.  
  109. static int gread  __ARGS__((char*, int));
  110. static int gwrite __ARGS__((char*, int));
  111.  
  112. static int gread(buf, n) /* deflated file reading */
  113. char *buf; register n;
  114. {
  115.    if ((n = unzread(buf, n)) == -1) {
  116.       (void)fprintf(myout, "Tar: unzip error: %s\n", ziperrlist[ziperror]);
  117.    }
  118.    return n;
  119. }
  120.  
  121. static int gwrite(buf, n) /* deflated file reading */
  122. char *buf; register n;
  123. {
  124.    if ((n = zipwrite(buf, n)) == -1) {
  125.       (void)fprintf(myout, "Tar: unzip error: %s\n", ziperrlist[ziperror]);
  126.    }
  127.    return n;
  128. }
  129.  
  130. static int ziperr __ARGS__((void))
  131. {
  132.    (void)fprintf(stderr, "Tar: zip error: %s\n", ziperrlist[ziperror]);
  133.    return ziperror == ZNOMEM ? ESMALL : ERINIT;
  134. }
  135.  
  136. #ifndef USE_COMPRESS
  137. static int twofault __ARGS__((char*, int));
  138.  
  139. /*ARGSUSED2*/ static int twofault(buf, n)
  140. char *buf; register n;
  141. {
  142. #ifdef __TURBOC__
  143.    (void)buf; (void)n;
  144. #endif
  145.    return -1;
  146. }
  147. #endif
  148.  
  149. /*ARGSUSED*/ static int onefault(n)
  150. int n;
  151. {
  152. #ifdef __TURBOC__
  153.    (void)n;
  154. #endif
  155.    return -1;
  156. }
  157.  
  158. static int (*pread) __ARGS__((char*, int)) = sread;
  159. static int (*pwrite)__ARGS__((char*, int)) = swrite;
  160. static int (*pback) __ARGS__((int))        = sback;
  161.  
  162. static int (*lread) __ARGS__((char*, int)) = sread;
  163. static int (*lwrite)__ARGS__((char*, int)) = swrite;
  164. static int (*lback) __ARGS__((int))        = sback;
  165. static int (*rcount)__ARGS__((char*, int)) = sread;
  166.  
  167. static int cntread  __ARGS__((char*, int));
  168.  
  169. int cntread(buf, n)
  170. char *buf; register n;
  171. {
  172.    if ((n = (*rcount)(buf, n)) != -1) {
  173.       allblock += (BLKSIZE-1 + (unsigned)n) / BLKSIZE;
  174.    }
  175.    return n;
  176. }
  177.  
  178. static void talign(i)
  179. long i;
  180. {
  181.    if (i % BLKSIZE) {
  182.       (void)fprintf(myout, "Tar: tape blocksize error\n");
  183.       if (!i_flag) done(ERREAD);
  184.    }
  185. }
  186.  
  187. void printbs(bs)
  188. int bs;
  189. {
  190.    if (v_flag) (void)fprintf(myout, "Tar: blocksize = %d\n", bs);
  191. }
  192.  
  193. static void wrerror __ARGS__((void))
  194. {
  195.    (void)fprintf(myout, "Tar: tape write error\n");
  196.    done(EWRITE);
  197. }
  198.  
  199. static int indget;
  200. static int eof_already = FALSE;
  201. static int got_length;
  202. static int indput;
  203.  
  204. static int getbyte __ARGS__(( void ))
  205. {
  206.    if (eof_already) goto end;
  207.    if (indget >= got_length) {
  208.       if (pksize == 0) {
  209.          if ((got_length = (*lread)(pk_inp, MAXBLOCK*BLKSIZE)) < 0) goto err;
  210.          if ((sa.st_mode & S_IFMT) == S_IFCHR) talign((long)got_length);
  211.          pksize = got_length;
  212.          if ((pksize % BLKSIZE) == 0) printbs(pksize/BLKSIZE);
  213.       } else {
  214.          if (got_length < pksize || got_length % BLKSIZE) goto end;
  215.          if ((got_length = (*lread)(pk_inp, pksize)) < 0) goto err;
  216.       }
  217.       if (got_length < 1) goto end;
  218.       indget = 0;
  219.    }
  220.    return ((unsigned char *)pk_inp)[indget++];
  221. err:
  222.    (void)fprintf(myout, rerror);
  223.    done(ERREAD);
  224. end:
  225.    eof_already = TRUE;
  226.    return EOF;
  227. }
  228.  
  229. static void pkflush __ARGS__((void))
  230. {
  231. #ifdef MSDOS
  232.    if (devtype != DEV_FILE && devtype != DEV_FLOP)
  233. #else
  234.    if (!isfile)
  235. #endif
  236.       while (indput < pksize) pk_out[indput++] = 0;
  237.  
  238.    if ((*lwrite)(pk_out, indput) < indput) wrerror();
  239.    indput = 0;
  240. }
  241.  
  242. static void putbyte(c)
  243. register c;
  244. {
  245.    if (indput >= pksize) {
  246. #ifndef pksize
  247.       /* Buffer size must not be less then 512 bytes, so we */
  248.       /* can wait for blocksize will be detected by reading */
  249.       if (indput < BLKSIZE) goto put;
  250.       if (pksize < BLKSIZE) pksize = BLKSIZE;
  251. #endif
  252.       pkflush();
  253.    }
  254. put:
  255.    pk_out[indput++] = c;
  256. }
  257.  
  258. int initape(name)
  259. char *name;
  260. {
  261. #ifdef UNIX
  262.    char tn[10]; register char *n;
  263. #endif
  264. #ifdef MSDOS
  265.    register k;
  266. #endif
  267.  
  268.    handle = -1;
  269.  
  270.    pread  = lread  = sread;
  271.    pwrite = lwrite = swrite;
  272.    pback  = lback  = sback;
  273.  
  274.    if (name && name[0]=='-' && name[1]==0) {
  275.       if ((a_flag && !c_flag) || d_flag) {
  276.          (void)fprintf(stderr, "Tar: can\'t update stdout\n");
  277.          return ERRARG;
  278.       }
  279. #ifdef myinp
  280.       if (j_flag
  281. #  ifndef MSDOS
  282.           || w_flag
  283. #  endif
  284.          ) {
  285.          (void)fprintf(stderr, "Tar: input must be free\n");
  286.          return ERRARG;
  287.       }
  288. #endif
  289.       handle = a_flag ? /* stdout */ 1 : /* stdin */ 0;
  290.       myout  = stderr;
  291.    } else {
  292. #ifdef UNIX
  293.       if (name && name[0]) {
  294.          n = name;
  295.       } else {
  296.          n = strcpy(tn, "/dev/mt0"); tn[7] = (ndrive & 7) | '0';
  297.       }
  298.       handle = c_flag ? creat(n, 0666) :
  299.                         open (n, a_flag && !d_flag ? O_RDWR : O_RDONLY);
  300.       if (handle < 0) {
  301.          cantopen(n); return ERINIT;
  302.       }
  303. #endif
  304.  
  305. #ifdef MSDOS
  306.       if (!name || !name[0]) {
  307.          devtype = DEV_FLOP;
  308.      inidisk();
  309.       } else if ((k=qparse(name)) != FALSE) {
  310.          if (k != TRUE) return ERRARG;
  311.          pread   = lread  = qread;
  312.          pwrite  = lwrite = qwrite;
  313.          pback   = lback  = qback;
  314.          devtype = DEV_QIC2;
  315.       } else {
  316.          if (!k_flag && defdev(name)==0) k_flag = TRUE;
  317.          if (k_flag) {
  318.             devtype = DEV_FLOP;
  319.         inidisk();
  320.          } else {
  321.             handle = open(name, !a_flag || d_flag ? O_RDONLY+O_BINARY :
  322.                                  c_flag ? O_CREAT+O_TRUNC+O_WRONLY+O_BINARY :
  323.                                           O_RDWR+O_BINARY,
  324.                                 S_IREAD+S_IWRITE);
  325.             if (handle < 0) {
  326.                cantopen(name); return ERINIT;
  327.             }
  328.             devtype = DEV_FILE;
  329.          }
  330.       }
  331.       if (devtype == DEV_FLOP) {
  332.          pread  = lread  = dread;
  333.          pwrite = lwrite = dwrite;
  334.          pback  = lback  = dback;
  335.       }
  336. #endif
  337.    }
  338.